package com.ea.eadp.nexus.test.pageDefinition;
import org.openqa.selenium.By;
import org.openqa.selenium.ElementNotVisibleException;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.interactions.Actions;
import org.testng.Assert;

import com.ea.eadp.nexus.test.common.PageOperation;
import com.ea.eadp.nexus.test.common.SystemProperties;
import com.ea.eadp.nexus.test.common.TestUtil;

public class XfinitySignupPage extends BasePage {
    public static final String DEFAULTURI = baseUri + TestUtil.SignupXfinityConnectURI();
    public static final String REDIRECTURI = SystemProperties.instance().getProperty(SystemProperties.RedirectUri);
    public static final String CONTINUEWITHOUTEAACCOUNTURI = "localhost";

    public static final String XPATHOFNOTMEETXFINITYREQUIREMENT = "//div[@id='panel-error-create']/div[1]";
    public static final String ERRORMESSAGENOTMEETXFINITYREQUIREMENT = "Sorry, you don't meet the requirements to access Xfinity Games. Would you like to continue without an EA Account to play E rated games only?";
    public static final String XPATHOFNOTCHECKINGEATOS = "//div[@id='panel-error-read-accept']/div[1]";
    public static final String ERRORMESSAGEOFNOTCHECKINGEATOS = "You must accept the Terms of Service, Privacy and Cookie Policy, and Xfinity Games Terms of Use to continue.";
    public static final String XPATHOFNOTCHECKINGCOMCASTPP = "//div[@id='panel-error-share-info']/div";
    public static final String ERRORMESSAGEOFNOTCHECKINGCOMCASTPP = "You must consent to share your data with Comcast to continue.";
    public static final String XPATHOFEMAILERROR = "//div[@id='panel-error-create']/div[1]";
    public static final String ERRORMESSAGEOFEMAIL = "Please enter a valid email.";
    public static final String XPATHOFORIGINIDERROR = "//div[@id='panel-error-origin-id']/div[1]";
    public static final String ERRORMESSAGEOFMISSINGORIGINID = "ID must be specified.";
    public static final String ERRORMESSAGEOFTOOSHORTORIGINID = "ID must be between 4 and 16 characters.";
    public static final String ERRORMESSAGEOFTOOLONGORIGINID = "ID must be between 4 and 16 characters.";
    public static final String ERRORMESSAGEOFINVALIDORIGINID = "ID contains a prohibited word or character.";
    public static final String XPATHOFPASSWORDERROR = "//div[@id='panel-error-password']/div[1]";
    public static final String ERRORMESSAGEOFMISSINGPASSWORD = "Password must be specified.";
    public static final String ERRORMESSAGENOTMEETPASSWORDREQUIREMENT = "Password does not meet requirements.";
    public static final String ERRORMESSAGEPASSWORDCONTAINUNSUPPORTEDCHARACTER = "Password contains an unsupported character.";
    public static final String XPATHOFDOBERROR = "//div[@id='panel-error-dob']/div[1]";
    public static final String ERRORMESSAGEOFMISSINGDOB = "Date of Birth must be specified.";
    public static final String ERRORMESSAGEOFINVALIDDOB = "Invalid Date of Birth.";
    public static final String XPATHOFREAPTCHAERROR = "//div[@id='panel-error-captcha']/div[1]";
    public static final String ERRORMESSAGEOFMISSINGREAPTCHA = "Missing CAPTCHA verification.";

    private static final String signinLinkXpath = "//div[@id='container']/div[1]/span/a";
    private static final String tosCheckboxXpath = "//div[@id='panel-optin']/div[2]/span";
    private static final String comcastPPCheckboxXpath = "//div[@id='panel-optin']/div[4]/span";
    private static final String continueButtonXpath = "//div[@id='panel-splash']/div[3]/a/span";
    private static final String continueWithoutAnEAAccountXpath = XPATHOFNOTMEETXFINITYREQUIREMENT + "/a";
    private static final String showHidePasswordXpath = "//div[@id='panel-profile']/div[7]/div/label";

    private static final String headerXpath = "//div[@id='container']/div[1]/span";
    private static final String titleXpath = "//div[@id='panel-header']/div/div";
    private static final String emailPlaceholderXpath = "//div[@id='panel-splash']/div[1]/div[2]/div[2]/div[2]";
    private static final String originIdPlaceholderXpath = "//div[@id='panel-profile']/div[3]/div[2]/div[2]/div[2]";
    private static final String passwordPlaceholderXpath = "//div[@id='panel-profile']/div[6]/div[2]/div[2]/div[2]";
    private static final String dobPlaceholderXpath = "//div[@id='panel-profile']/div[10]/div[2]/div[2]/div[2]";
    private static final String captchaPlaceholderXpath = "//div[@id='panel-captcha']/div[1]/div[3]/div[2]/div[2]";
    private static final String tosXpath = "//div[@id='panel-optin']/div[2]/label";
    private static final String comcastPPXpath = "//div[@id='panel-optin']/div[4]/label";

    public XfinitySignupPage(WebDriver driver) {
        super(driver, XfinitySignupPage.class);
        this.setUri(DEFAULTURI);
    }

    public void validateStringsOnTheFirstPage() throws Exception {
        validatePageContent(headerXpath, "Already have an EA Account? Log in");
        validatePageContent(titleXpath, "Sign up for an EA Account\nto access XFINITY Games");
        validatePageContent(emailPlaceholderXpath, "Email");
    }

    public void validateStringsOnTheSecondPage() throws Exception {
        validatePageContent(headerXpath, "Already have an EA Account? Log in");
        validatePageContent(titleXpath, "Sign up for an EA Account\nto access XFINITY Games");
        validatePageContent(originIdPlaceholderXpath, "Create a Public ID");
        validatePageContent(passwordPlaceholderXpath, "Password");
        validatePageContent(dobPlaceholderXpath, "MM/DD/YYYY");
        validatePageContent(captchaPlaceholderXpath, "Security Text");
        validatePageContent(tosXpath, "I have read and accept EA's Terms of Service / EA's Privacy and Cookie Policy / Xfinity Games Terms of Use");
        validatePageContent(comcastPPXpath, "By creating an EA/Origin Account for use with XFINITY Games Powered by EA, I agree that my EA Account information will be shared with Comcast and used consistently with the Comcast Privacy Policy");
    }

    public void validateStringsOnTheThirdPage() throws Exception {
        validatePageContent("//div[@id='panel-header']/div/div", "Welcome ");
        validatePageContent("//div[@id='panel-header']/div/div", "Your new EA Account is");
        validatePageContent("//div[@id='panel-header']/div/div", "ready to go.");
    }

    public void setSignupEmail(final String email) {
        driver.switchTo().window(this.operationWindowHandle);
        log.info(email);
        PageOperation.SendKeyToElementAfterWait(driver, "email", email);
    }

    public void clickSigninLink() throws Exception {
        driver.switchTo().window(this.operationWindowHandle);
        driver.findElement(By.xpath(signinLinkXpath)).click();
        for (int i = 0; i < 5; i++) {
            Thread.sleep(1000);
            if (TestUtil.getCurrentUrl(driver).contains("p/xfinity/login?")) return;
        }
        throw new Exception("validate goes to redirect uri.");
    }

    public void clickContinueButtonToSignup() throws Exception {
        clickContinueButton();
        identifierId = "captcha";
        PageOperation.WebDriverWait(driver, identifierId);
        driver.findElement(By.id(identifierId));
        validateStringsOnTheSecondPage();
    }

    public void clickContinueButtonToSignin() throws Exception {
        clickContinueButton();
        identifierId = "panel-login";
        PageOperation.WebDriverWait(driver, identifierId);
        driver.findElement(By.id(identifierId));
    }

    public void clickContinueButtonAndValidate(final String path, final String regex) throws Exception {
        clickContinueButton();
        validatePageContent(path, regex);
    }

    public void setSignupOriginId(final String originId) {
        driver.switchTo().window(this.operationWindowHandle);
        log.info(originId);
        PageOperation.SendKeyToElementAfterWait(driver, "originId", originId);
    }

    public void setSignupPassword(final String password) {
        driver.switchTo().window(this.operationWindowHandle);
        log.info(password);
        PageOperation.SendKeyToElementAfterWait(driver, "password", password);
    }

    public void clickShowHidePassword(final boolean showPassword) {
        String[] texts = null;
        if (showPassword) 
            texts = new String[] { "show", "hide" };
        else
            texts = new String[] { "hide", "show" };
        Assert.assertEquals(driver.findElement(By.xpath(showHidePasswordXpath)).getText(), texts[0]);
        driver.findElement(By.xpath(showHidePasswordXpath)).click();
        Assert.assertEquals(driver.findElement(By.xpath(showHidePasswordXpath)).getText(), texts[1]);
    }

    public void setDob(final String dob) {
        driver.switchTo().window(this.operationWindowHandle);
        log.info(dob);
        PageOperation.SendKeyToElementAfterWait(driver, "dob", dob);
    }

    public void setCaptcha(final String value) {
        driver.switchTo().window(this.operationWindowHandle);
        log.info(value);
        PageOperation.SendKeyToElementAfterWait(driver, "captcha", value);
    }

    public void refreshCaptcha() {
        driver.switchTo().window(this.operationWindowHandle);
        log.info("refresh captcha.");
        String orignalSrc = driver.findElement(By.id("captchaImg")).getAttribute("src");
        driver.findElement(By.id("captchaImg")).click();
        Assert.assertNotEquals(orignalSrc, driver.findElement(By.id("captchaImg")).getAttribute("src"));
    }

    public void checkboxEATOS(final boolean check) {
        driver.switchTo().window(this.operationWindowHandle);

        if (check && !driver.findElement(By.id("readAccept")).isSelected()) {
            driver.findElement(By.xpath(tosCheckboxXpath)).click();
        } else if (!check && driver.findElement(By.id("readAccept")).isSelected()) {
            driver.findElement(By.xpath(tosCheckboxXpath)).click();
        }
    }

    public void checkboxComcastPP(final boolean check) {
        driver.switchTo().window(this.operationWindowHandle);

        if (check && !driver.findElement(By.id("shareInfo")).isSelected()) {
            driver.findElement(By.xpath(comcastPPCheckboxXpath)).click();
        } else if (!check && driver.findElement(By.id("shareInfo")).isSelected()) {
            driver.findElement(By.xpath(comcastPPCheckboxXpath)).click();
        }
    }

    private void clickCreateAccountButton() throws Exception {
        driver.switchTo().window(this.operationWindowHandle);
        Thread.sleep(1000);
        clickBlank("//div[@id='panel-header']/div/div");
        Actions actions = new Actions(driver);
        actions.moveToElement(driver.findElement(By.cssSelector(".btn-create"))).click().perform();
        Thread.sleep(1000);
    }

    public void clickCreateAccountButtonAndWait() throws Exception {
        clickCreateAccountButton();
        identifierId = "panel-header";
        PageOperation.WebDriverWaitByCssSelector(driver, ".btn-continue");
        driver.findElement(By.id(identifierId));
        validateStringsOnTheThirdPage();
    }

    public void clickCreateAccountButtonAndValidate(final String path, final String regex) throws Exception {
        clickCreateAccountButton();
        validatePageContent(path, regex);
    }

    public void clickContinueButtonOnTheThirdPageAndWait() throws Exception {
        driver.switchTo().window(this.operationWindowHandle);
        driver.findElement(By.xpath("//div[@id='panel-header']/div[2]/a/span")).click();
        for (int i = 0; i < 5; i++) {
            Thread.sleep(1000);
            if (TestUtil.getCurrentUrl(driver).contains(REDIRECTURI) || TestUtil.getCurrentUrl(driver).contains("s2")) {
                if(TestUtil.getCurrentUrl(driver).contains("?code=")) return;
                else break;
            }
        }
        throw new Exception("validate goes to redirect uri.");
    }

    public void clickContinueWithoutAnEAAccount() throws Exception {
        driver.switchTo().window(this.operationWindowHandle);
        driver.findElement(By.xpath(continueWithoutAnEAAccountXpath)).click();
        for (int i = 0; i < 5; i++) {
            Thread.sleep(1000);
            if (TestUtil.getCurrentUrl(driver).contains(CONTINUEWITHOUTEAACCOUNTURI) || TestUtil.getCurrentUrl(driver).contains("s2")) {
                if (!TestUtil.getCurrentUrl(driver).contains("?code=")) return;
                else break;
            }
        }
        throw new Exception("validate goes to redirect uri.");
    }

    public String getMaxLengthForOriginID() {
        driver.switchTo().window(this.operationWindowHandle);
        return driver.findElement(By.id("originId")).getAttribute("maxlength");
    }

    private void clickContinueButton() throws Exception {
        driver.switchTo().window(this.operationWindowHandle);
        driver.findElement(By.xpath(continueButtonXpath)).click();
        Thread.sleep(1000);
        try {
            driver.findElement(By.xpath(continueButtonXpath)).click();
        } catch (ElementNotVisibleException e) {
            return;
        } catch (NoSuchElementException e) {
            return;
        }
    }

    public void clickBlank(String xpath) {
        org.openqa.selenium.WebElement element = driver.findElement(By.xpath(xpath));
        Actions actions = new Actions(driver);
        actions.moveToElement(element).click().perform();
        TestUtil.sleep(1);
    }
}
